package cn.lisens.demo.config;

import java.time.Duration;

import javax.net.ssl.SSLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import reactor.netty.http.client.HttpClient;

@Configuration
@EnableConfigurationProperties(WebClientProperties.class)
public class WebClientConfig {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Bean
	public WebClient.Builder webClientBuilder(WebClientProperties properties) throws SSLException {
		SslContext sslContext = SslContextBuilder.forClient()
			    .trustManager(InsecureTrustManagerFactory.INSTANCE) // 信任所有证书
			    .build();
		 
		HttpClient httpClient = HttpClient.create()
//				.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时
				.responseTimeout(Duration.ofSeconds(4))// 总请求超时
				.secure(sslSpec -> sslSpec.sslContext(sslContext));
                
		return WebClient.builder()
				.baseUrl(properties.getUrl())
				.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024))
				.clientConnector(new ReactorClientHttpConnector(httpClient))
				.filter(logRequest());
	}
	
	/**
	 * 后面再添加filter对header和cookie修改，这里无法监视到。
	 * @return
	 */
	private ExchangeFilterFunction logRequest() {
        return (clientRequest, next) -> {
            logger.info("webclient请求: {} {}", clientRequest.method(), clientRequest.url());
            clientRequest.headers()
                    .forEach((name, values) -> values.forEach(value -> logger.info("请求header:{}={}", name, value)));
            clientRequest.cookies()
            		.forEach((name, values) -> values.forEach(value -> logger.info("请求cookie:{}={}", name, value)));
            return next.exchange(clientRequest);
        };
    }
	
}
